import platform
import threading
from tkinter import filedialog as fd

import fitz
import ttkbootstrap as ttk
import os
import tkinter as tk
import tkinter.messagebox as dialog


class Tools:

    def __init__(self):
        self.input_folder_path = None
        self.output_folder_path = None
        self.window = ttk.Window()
        self.window.title("PDF生成图片工具 v1.0")
        self.window.resizable(width=False, height=False)
        self.window.geometry('850x310')
        self.build()

    def run(self):
        self.window.mainloop()

    def build(self):
        ttk.Label(self.window, text="PDF 文件夹:").place(x=30, y=80)
        if platform.system() == 'Windows':
            self.input_folder = ttk.Entry(self.window, width=20)
        else:
            self.input_folder = ttk.Entry(self.window, width=15)
        self.input_folder.place(x=120, y=78)
        ttk.Button(self.window, text="选择文件夹", command=self.select_input_folder).place(x=300, y=78)

        ttk.Label(self.window, text="输出文件夹:").place(x=30, y=170)
        if platform.system() == 'Windows':
            self.output_folder = ttk.Entry(self.window, width=20)
        else:
            self.output_folder = ttk.Entry(self.window, width=15)
        self.output_folder.place(x=120, y=168)
        ttk.Button(self.window, text="选择文件夹", command=self.select_output_folder).place(x=300, y=168)

        # 分割线
        ttk.Separator(self.window, orient=tk.VERTICAL).pack(padx=15, pady=15, fill='y', expand=True)

        ttk.Label(self.window, text='日 志：').place(x=450, y=30)
        if platform.system() == 'Windows':
            self.log_text = ttk.ScrolledText(self.window, width=35, height=12)
            self.log_text.place(x=540, y=30)
            self.log_text.config(font=('Helvetica', 10))

        else:
            self.log_text = ttk.ScrolledText(self.window, width=35, height=13)
            self.log_text.place(x=520, y=30)
            self.log_text.config(font=('Helvetica', 13))
        self.log_text.insert(tk.INSERT, '欢迎使用本工具 \n\n')

        # 清空按钮
        ttk.Button(self.window, text="清 空", width=4, command=self.clean_log_text).place(x=450, y=70)

        # 开始按钮
        ttk.Button(self.window, text="开 始", width=4, command=self.start).place(x=630, y=260)

    def clean_log_text(self):
        self.log_text.delete(0.0, tk.END)
        self.log_text.insert(tk.INSERT, '欢迎使用本工具 \n\n')

    def start(self):
        # 校验
        if not self.input_folder_path:
            dialog.showerror(title='错误', message='PDF文件夹不能为空')
            return
        if not self.output_folder_path:
            dialog.showerror(title='错误', message='输出文件夹不能为空')
            return
        # 创建线程异步执行任务
        self.async_update_log_text("遍历目标文件夹...\n")
        s = threading.Thread(target=self.async_execute_tasks)
        s.daemon = True
        s.start()

    def select_input_folder(self):
        selected_folder = fd.askdirectory()
        self.input_folder_path = selected_folder
        self.input_folder.delete(0, tk.END)
        self.input_folder.insert(0, selected_folder)
        self.output_folder_path = selected_folder
        self.output_folder.delete(0, tk.END)
        self.output_folder.insert(0, selected_folder)

    def select_output_folder(self):
        selected_folder = fd.askdirectory()
        self.output_folder_path = selected_folder
        self.output_folder.delete(0, tk.END)
        self.output_folder.insert(0, selected_folder)

    def async_update_log_text(self, msg):
        self.log_text.after(0, lambda: self.update_log_text(msg))

    def update_log_text(self, msg):
        self.log_text.insert(tk.END, msg)
        self.log_text.see(tk.END)

    def async_execute_tasks(self):
        for pdf_file in os.listdir(self.input_folder_path):
            if os.path.isdir(os.path.join(self.input_folder_path, pdf_file)):
                continue
            if pdf_file.startswith('.'):
                continue
            if pdf_file.split('.')[-1] not in ["pdf", "PDF"]:
                self.async_update_log_text("{}不是 pdf 文件\n".format(pdf_file))
                continue
            pdf_path = os.path.join(self.input_folder_path, pdf_file)
            output_folder = os.path.join(self.output_folder_path, pdf_file.split('.')[0])
            self.pdf_to_images(pdf_path, output_folder)
        self.async_update_log_text("本次任务已完成，请检查输出文件夹！\n\n")

    def pdf_to_images(self, pdf_path, output_folder):
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        doc = fitz.open(pdf_path)
        count_page = doc.pageCount
        for i in range(count_page):
            # 保存路径
            save_path = os.path.join(output_folder, "page_{}.png".format(i + 1))
            if os.path.exists(save_path):
                continue
            page = doc[i]
            rotate = int(0)
            # 每个尺寸的缩放系数为2，这将为我们生成分辨率提高四倍的图像。
            zoom_x = 2.0
            zoom_y = 2.0
            trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
            pm = page.get_pixmap(matrix=trans, alpha=False)
            pm.save(save_path)
        self.async_update_log_text("文件名:{},图片导出完成！\n".format(pdf_path.split('/')[-1]))


if __name__ == '__main__':
    Tools().run()
